/*
 * Trip.java
 *
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.core.trip;

import java.awt.geom.Rectangle2D;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.fpdev.core.basenet.BNode;
import org.fpdev.core.basenet.BaseNetwork;
import org.fpdev.apps.rtemaster.gui.map.MapCanvas;
import org.fpdev.apps.rtemaster.gui.map.MapDrawable;
import org.fpdev.core.data.CoreDB;

public class Trip implements MapDrawable {

  private List<TripItem> items_;
  private int transitItemCount_;
  private int linkListID_; // the db id of the comma-separated link id list; only used in server mode
  private Type type_;
  private BNode startNode_;

  public enum Type {

    TRAVEL_TIME("tt"),
    NUM_TRANSFERS("nt"),
    NON_MOTORIZED("nm");
    private String xmlCode_;

    Type(String code) {
      xmlCode_ = code;
    }

    public String xmlCode() {
      return xmlCode_;
    }
  }

  public Trip(Type type, BNode startNode) {
    type_ = type;
    startNode_ = startNode;
    //System.out.println("trip startNode="+startNode.getID());
    items_ = new LinkedList<TripItem>();
    transitItemCount_ = 0;
    linkListID_ = 0;
  }

  public void addItem(TripItem item) {
    items_.add(item);
    if (item.getType() == TripItem.TRIP_TRANSIT) {
      transitItemCount_++;
    }
  }

  public int itemCount() {
    return items_.size();
  }

  public int transferCount() {
    return transitItemCount_ <= 0 ? 0 : transitItemCount_ - 1;
  }

  public int subItemCount() {
    Iterator<TripItem> items = items();
    int n = 0;
    while (items.hasNext()) {
      n += items.next().subItemCount();
    }
    return n;
  }

  public Iterator<TripItem> items() {
    return items_.iterator();
  }


  public void addLinkListToDB(CoreDB db) {
    String listStr = startNode_.getID()+",";

    for (Iterator<TripItem> items = items(); items.hasNext();) {
      TripItem item = items.next();
      if(item.getType() == TripItem.TRIP_BIKE || item.getType() == TripItem.TRIP_WALK || item.getType() == TripItem.TRIP_TRANSIT) {
        listStr += item.getItemName() + ",";
        List<Integer> itemList = item.getLinkIDList();
        for(Iterator<Integer> itemLinkIDs = itemList.iterator(); itemLinkIDs.hasNext();) {
          listStr += itemLinkIDs.next() + ",";
        }
      }
    }    
    listStr = listStr.substring(0, listStr.length()-1); // trim off last comma
    linkListID_ = db.initTripLinks(listStr);
    System.out.println("set linkListID = "+linkListID_);
  }

  public String getXml(BaseNetwork net) { //, String type) {
    String xml = "";
    Rectangle2D bbox = getBoundingBox();

    xml += "  <trip type=\"" + type_.xmlCode() + "\" start=\"" + getStart() + "\" end=\"" + getEnd() + "\" bx=\"" + bbox.getX() + "\" by=\"" + bbox.getY() + "\" bw=\"" + bbox.getWidth() + "\" bh=\"" + bbox.getHeight() + "\"";
    System.out.println("check linkListID = "+linkListID_);
    if (linkListID_ > 0) {
      xml += " listid=\"" + linkListID_ + "\"";
    }
    xml += ">\n";

    Iterator<TripItem> items = items();
    while (items.hasNext()) {
      xml += items.next().getXml(net);
    }

    xml += "  </trip>\n";

    return xml;
  }

  public int getStart() {
    return items_.get(0).getStart();
  }

  public int getEnd() {
    return items_.get(items_.size() - 1).getEnd();
  }

  public void draw(MapCanvas canvas) {
    Iterator<TripItem> items = items();
    while (items.hasNext()) {
      items.next().draw(canvas);
    }
  }

  public Rectangle2D getBoundingBox() {
    Rectangle2D box = null;
    Iterator<TripItem> items = items();
    while (items.hasNext()) {
      TripItem item = items.next();
      Rectangle2D ibox = item.getBoundingBox();
      if (ibox != null) {
        if (box == null) {
          box = ibox;
        } else {
          box = box.createUnion(ibox);
        }
      }
    }
    return box;
  }
}

























